/*
 *  $Id$
 *  Copyright [2010] [Panxiaobo] 
 *  Licensed under the Apache License, Version 2.0 (the "License"); 
 *  you may not use this file except in compliance with the License. 
 *  You may obtain a copy of the License at
 *  
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 *  Unless required by applicable law or agreed to in writing, software 
 *  distributed under the License is distributed on an "AS IS" BASIS, 
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 *  See the License for the specific language governing permissions and 
 *  limitations under the License. 
 */
package pxb.openid.op;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import pxb.openid.OpenIdException;

/**
 * 使用AES算法加密Association
 * 
 * @author Panxiaobo
 * 
 */
public class AESAssociationManager extends EncodedAssociationManager {
    /**
     * AES密钥
     */
    protected SecretKeySpec skeySpec;

    /**
     * 随机生成AES加密的密钥,并且可以通过
     * 
     * @see #setKey(byte[])方法设置认为的密钥
     */
    public AESAssociationManager() {
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128, new SecureRandom());

            SecretKey secretKey;
            secretKey = kg.generateKey();
            byte[] raw = secretKey.getEncoded();
            setKey(raw);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    final protected byte[] doDecode(byte[] bytes) {
        try {
            Cipher decodeCipher = Cipher.getInstance("AES");
            decodeCipher.init(Cipher.DECRYPT_MODE, skeySpec);
            return decodeCipher.doFinal(bytes);
        } catch (InvalidKeyException e) {
            throw new OpenIdException(e);
        } catch (IllegalBlockSizeException e) {
            throw new OpenIdException(e);
        } catch (BadPaddingException e) {
            throw new OpenIdException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new OpenIdException(e);
        } catch (NoSuchPaddingException e) {
            throw new OpenIdException(e);
        }
    }

    final protected byte[] doEncode(byte[] bytes) {
        try {
            Cipher encodeCipher = Cipher.getInstance("AES");
            encodeCipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            return encodeCipher.doFinal(bytes);
        } catch (InvalidKeyException e) {
            throw new OpenIdException(e);
        } catch (IllegalBlockSizeException e) {
            throw new OpenIdException(e);
        } catch (BadPaddingException e) {
            throw new OpenIdException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new OpenIdException(e);
        } catch (NoSuchPaddingException e) {
            throw new OpenIdException(e);
        }
    }

    /**
     * 设置AES密钥
     * 
     * @param key
     */
    public void setKey(byte[] key) {
        skeySpec = new SecretKeySpec(key, "AES");
    }

}
